/* Copyright 2009
 *
 * This program and the accompanying materials
 * are made available under the terms of the
 * Eclipse Public License v1.0 which accompanies
 * this distribution, and is available at
 *
 * 		http://www.eclipse.org/legal/epl-v10.html
 *
 * Unless required by applicable law or agreed to in
 * writing, software distributed under the License is
 * distributed on an "AS IS" BASIS, WITHOUT WARRANTIES
 * OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing
 * permissions and limitations under the License.
 *
 * Contributors:
 * 	   IBM Corporation - initial API and implementation for JDT/DLTK
 *     Sean W. Quinn - adoption for use with PHP from various sources.
 */
package org.eclipse.php.core;

import org.eclipse.core.runtime.IProgressMonitor;
import org.eclipse.dltk.core.ICodeAssist;
import org.eclipse.dltk.core.IOpenable;
import org.eclipse.dltk.core.IParent;
import org.eclipse.dltk.core.ISourceReference;
import org.eclipse.dltk.core.IType;
import org.eclipse.dltk.core.WorkingCopyOwner;

/**
 * Represents an entire PHP type root (either an <code>IProgramUnit</code> or an
 * <code>IScriptFile</code>).
 *
 * @see IProgramUnit Note that methods {@link #findPrimaryType()} and
 *      {@link #getElementAt(int)} were already implemented in this interface
 *      respectively since version 3.0 and version 1.0.
 * @see IScriptFile Note that method
 *      {@link #getWorkingCopy(WorkingCopyOwner, IProgressMonitor)} was already
 *      implemented in this interface since version 3.0.
 * @since 3.3
 * @noimplement This interface is not intended to be implemented by clients.
 */
public interface ITypeRoot extends IPHPElement, IParent, IOpenable, ISourceReference, ICodeAssist {

	/**
	 * Finds the primary type of this PHP type root (that is, the type with the
	 * same name as the compilation unit, or the type of a class file), or
	 * <code>null</code> if no such a type exists.
	 *
	 * @return the found primary type of this PHP type root, or
	 *         <code>null</code> if no such a type exists
	 */
	IType findPrimaryType();

	/**
	 * Returns the smallest element within this PHP type root that includes the
	 * given source position (that is, a method, field, etc.), or
	 * <code>null</code> if there is no element other than the PHP type root
	 * itself at the given position, or if the given position is not within the
	 * source range of the source of this PHP type root.
	 *
	 * @param position a source position inside the PHP type root
	 * @return the innermost PHP element enclosing a given source position or
	 *         <code>null</code> if none (excluding the PHP type root).
	 * @throws PHPModelException if the PHP type root does not exist or if an
	 *             exception occurs while accessing its corresponding resource
	 */
	IPHPElement getElementAt(final int position) throws PHPModelException;

	/**
	 * Returns a shared working copy on this compilation unit or class file
	 * using the given working copy owner to create the buffer. If this is
	 * already a working copy of the given owner, the element itself is
	 * returned. This API can only answer an already existing working copy if it
	 * is based on the same original PHP type root AND was using the same
	 * working copy owner (that is, as defined by {@link Object#equals}).
	 * <p>
	 * The life time of a shared working copy is as follows:
	 * <ul>
	 * <li>The first call to
	 * {@link #getWorkingCopy(WorkingCopyOwner, IProgressMonitor)} creates a new
	 * working copy for this element</li>
	 * <li>Subsequent calls increment an internal counter.</li>
	 * <li>A call to {@link IProgramUnit#discardWorkingCopy()} decrements the
	 * internal counter.</li>
	 * <li>When this counter is 0, the working copy is discarded.
	 * </ul>
	 * So users of this method must discard exactly once the working copy.
	 * <p>
	 * Note that the working copy owner will be used for the life time of the
	 * shared working copy, that is if the working copy is closed then reopened,
	 * this owner will be used. The buffer will be automatically initialized
	 * with the original's PHP type root content upon creation.
	 * <p>
	 * When the shared working copy instance is created, an ADDED
	 * IPHPElementDelta is reported on this working copy.
	 * </p>
	 * <p>
	 * A working copy can be created on a not-yet existing compilation unit. In
	 * particular, such a working copy can then be committed in order to create
	 * the corresponding compilation unit.
	 * </p>
	 * <p>
	 * Note that possible problems of this working copy are reported using this
	 * method only if the given working copy owner returns a problem requestor
	 * for this working copy (see
	 * {@link WorkingCopyOwner#getProblemRequestor(IProgramUnit)} .
	 * </p>
	 *
	 * @param owner the working copy owner that creates a buffer that is used to
	 *            get the content of the working copy
	 * @param monitor a progress monitor used to report progress while opening
	 *            this compilation unit or <code>null</code> if no progress
	 *            should be reported
	 * @throws PHPModelException if the contents of this element can not be
	 *             determined.
	 * @return a new working copy of this PHP type root using the given owner to
	 *         create the buffer, or this PHP type root if it is already a
	 *         working copy
	 */
	IProgramUnit getWorkingCopy(final WorkingCopyOwner owner, final IProgressMonitor monitor) throws PHPModelException;

}
